<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>泛娱乐知识图谱分析平台</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
    <div class="container">
        <!-- 侧边栏 -->
        <div class="sidebar">
            <div class="logo">
                <h1>泛娱乐知识图谱</h1>
                <p>探索娱乐世界的关联</p>
            </div>
            <ul class="menu">
                <li class="menu-item">
                    <a href="#" class="menu-link active" data-target="ner">
                        <i class="fas fa-tags"></i>
                        <span>命名实体识别</span>
                    </a>
                </li>
                <li class="menu-item">
                    <a href="#" class="menu-link" data-target="re">
                        <i class="fas fa-project-diagram"></i>
                        <span>关系抽取</span>
                    </a>
                </li>
                <li class="menu-item">
                    <a href="#" class="menu-link" data-target="kg">
                        <i class="fas fa-brain"></i>
                        <span onclick="redirectImmediately()">知识图谱</span>
                    </a>
                </li>
{#                <li class="menu-item">#}
{#                    <a href="#" class="menu-link" data-target="search">#}
{#                        <i class="fas fa-search"></i>#}
{#                        <span>知识查询</span>#}
{#                    </a>#}
{#                </li>#}
            </ul>
        </div>

        <!-- 主内容区域 -->
        <div class="main-content">
            <div class="header">
{#                <div class="search-box">#}
{#                    <input type="text" id="global-search" placeholder="搜索演员、电影、歌曲...">#}
{#                    <button onclick="performSearch()"><i class="fas fa-search"></i></button>#}
{#                </div>#}
                <div class="user-info">
                    <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="用户头像">
                    <div style="margin-right: 30px">
                        <h3>知识图谱管理员</h3>
                        <p>Admin</p>
                    </div>
                </div>
            </div>

            <!-- 命名实体识别内容 -->
            <div class="content-section" id="ner">
                <div class="card">
                    <div class="card-header">
                        <h2 class="card-title">命名实体识别</h2>
                        <button class="graph-btn" onclick="clearNerInput()"><i class="fas fa-redo"></i></button>
                    </div>
                    <div class="input-area">
                        <textarea id="ner-input" placeholder="请输入文本内容，例如：周杰伦出演了头文字D电影，并演唱了七里香这首歌..."></textarea>
                        <button class="btn" onclick="performNer()">
                            <i class="fas fa-cogs"></i> 识别实体
                        </button>
                    </div>
                    <div class="result-container" id="ner-results">
                        <p>识别结果将显示在这里...</p>
                    </div>
                </div>
            </div>

            <!-- 关系抽取内容 -->
            <div class="content-section" id="re" style="display: none;">
                <div class="card">
                    <div class="card-header">
                        <h2 class="card-title">关系抽取</h2>
                        <button class="graph-btn" onclick="clearReInput()"><i class="fas fa-redo"></i></button>
                    </div>
                    <div class="input-area">
                        <textarea id="re-input" placeholder="请输入文本内容，例如：周杰伦导演了不能说的秘密这部电影，方文山为青花瓷作词..."></textarea>
                        <button class="btn" onclick="performRe()">
                            <i class="fas fa-link"></i> 抽取关系
                        </button>
                    </div>
                    <div class="result-container" id="re-results">
                        <p>关系抽取结果将显示在这里...</p>
                    </div>
                </div>
            </div>

            <!-- 知识图谱展示内容 -->
            <div class="content-section" id="kg" style="display: none;">
                <div class="card">
                    <div class="card-header">
                        <h2 class="card-title">📈 知识图谱</h2>
{#                        <div class="graph-controls">#}
{#                            <button class="graph-btn" onclick="zoomIn()"><i class="fas fa-search-plus"></i></button>#}
{#                            <button class="graph-btn" onclick="zoomOut()"><i class="fas fa-search-minus"></i></button>#}
{#                            <button class="graph-btn" onclick="refreshGraph()"><i class="fas fa-sync-alt"></i></button>#}
{#                        </div>#}
                    </div>
                    <div class="visualization-panel">
                        <div id="network" class="network-container"></div>
                    </div>
{#                    <div class="graph-container">#}
{#                        <a class="knowlige" onclick="redirectImmediately()">可视化页面</a>#}
{#                    </div>#}
                </div>
            </div>

            <!-- 知识查询内容 -->
{#            <div class="content-section" id="search" style="display: none;">#}
{#                <div class="card">#}
{#                    <div class="card-header">#}
{#                        <h2 class="card-title">知识查询结果</h2>#}
{#                        <button class="graph-btn" onclick="exportResults()"><i class="fas fa-download"></i></button>#}
{#                    </div>#}
{#                    <div class="result-container" id="search-results">#}
{#                        <p>搜索结果显示在这里...</p>#}
{#                    </div>#}
{#                </div>#}
{#            </div>#}
        </div>
    </div>
    <script src="{{ url_for('static', filename='js/graph.js') }}"></script>
    <script>
        // 立即跳转
        function redirectImmediately() {
            window.location.href = "/graph";
        }
        // 菜单切换功能
        document.querySelectorAll('.menu-link').forEach(link => {
            link.addEventListener('click', function(e) {
                e.preventDefault();

                // 更新活动菜单项
                document.querySelectorAll('.menu-link').forEach(item => {
                    item.classList.remove('active');
                });
                this.classList.add('active');

                // 显示对应内容
                const target = this.getAttribute('data-target');
                if (target) {
                    document.querySelectorAll('.content-section').forEach(section => {
                        section.style.display = 'none';
                    });
                    document.getElementById(target).style.display = 'block';

                    // 如果是知识图谱菜单，初始化图谱
                    if (target === 'kg') {
                        initKnowledgeGraph();
                    }
                }
            });
        });

        // 命名实体识别功能
        async function performNer() {
            const text = document.getElementById('ner-input').value.trim();
            if (!text) {
                alert('请输入文本内容');
                return;
            }

            try {
                const response = await fetch('http://127.0.0.1:6969/lstm_crf_predict', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ text: text })
                });

                const data = await response.json();
                displayNerResults(data);
            } catch (error) {
                console.error('NER Error:', error);
                alert('实体识别失败');
            }
        }

        function displayNerResults(data) {
            const resultsContainer = document.getElementById('ner-results');
            if (data.success == 200) {
                console.log(data.result.text)
                let html = `<h3>识别到的实体:</h3>`;
                {#data.result.forEach(entity => {#}
                html += `<span class="entity-tag">${data.result.text} -> (${data.result.type})</span>`;
                // });
                html += `<p><small>原始文本: ${data.text}</small></p>`;
                resultsContainer.innerHTML = html;
            } else {
                resultsContainer.innerHTML = '<p>未识别到实体</p>';
            }
        }

        function clearNerInput() {
            document.getElementById('ner-input').value = '';
            document.getElementById('ner-results').innerHTML = '<p>识别结果将显示在这里...</p>';
        }

        // 关系抽取功能
        async function performRe() {
            const text = document.getElementById('re-input').value.trim();
            if (!text) {
                alert('请输入文本内容');
                return;
            }

            try {
                const response = await fetch('http://127.0.0.1:6868/casrel_predict', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ text: text })
                });

                const data = await response.json();
                displayReResults(data);
            } catch (error) {
                console.error('RE Error:', error);
                alert('关系抽取失败');
            }
        }

        function displayReResults(data) {
            console.log(data.success)
            const resultsContainer = document.getElementById('re-results');
            if (data.success == 200) {
                let html = `<h3>抽取到的关系:</h3>`;
                data.relations.spo_list.forEach(relation => {
                    html += `
                        <div class="relation-item">
                            <strong>${relation.subject}</strong> →
                            <strong>${relation.predicate}</strong> →
                            <strong>${relation.object}</strong>
                        </div>
                    `;
                });
                html += `<p><small>原始文本: ${data.text}</small></p>`;
                resultsContainer.innerHTML = html;
            } else {
                resultsContainer.innerHTML = '<p>未抽取到关系</p>';
            }
        }

        function clearReInput() {
            document.getElementById('re-input').value = '';
            document.getElementById('re-results').innerHTML = '<p>关系抽取结果将显示在这里...</p>';
        }

        // 知识图谱功能
        let graphSimulation;
        let graphZoom;

        async function initKnowledgeGraph() {
            try {
                const response = await fetch('/api/kg/graph?limit=30');
                const data = await response.json();
                renderKnowledgeGraph(data);
            } catch (error) {
                console.error('KG Error:', error);
            }
        }

        function renderKnowledgeGraph(data) {
            const width = document.getElementById('knowledge-graph').clientWidth;
            const height = document.getElementById('knowledge-graph').clientHeight;

            d3.select('#knowledge-graph').selectAll('*').remove();

            const svg = d3.select('#knowledge-graph')
                .attr('width', width)
                .attr('height', height);

            const g = svg.append('g');

            // 颜色映射
            const colorScale = d3.scaleOrdinal()
                .domain(["Person", "Movie", "Music", "TV", "Award", "Actor", "Singer", "Director"])
                .range(["#6c5ce7", "#fd79a8", "#00b894", "#fdcb6e", "#0984e3", "#d63031", "#e84393", "#00cec9"]);

            // 力导向图模拟
            graphSimulation = d3.forceSimulation(data.nodes)
                .force('link', d3.forceLink(data.links).id(d => d.id).distance(100))
                .force('charge', d3.forceManyBody().strength(-300))
                .force('center', d3.forceCenter(width / 2, height / 2));

            // 绘制连线
            const link = g.append('g')
                .attr('class', 'links')
                .selectAll('line')
                .data(data.links)
                .enter().append('line')
                .attr('stroke-width', 2)
                .attr('stroke', '#999')
                .attr('stroke-opacity', 0.6);

            // 绘制节点
            const node = g.append('g')
                .attr('class', 'nodes')
                .selectAll('circle')
                .data(data.nodes)
                .enter().append('circle')
                .attr('r', 8)
                .attr('fill', d => colorScale(d.type))
                .call(d3.drag()
                    .on('start', dragstarted)
                    .on('drag', dragged)
                    .on('end', dragended))
                .on('click', showNodeDetails);

            // 添加节点标签
            const text = g.append('g')
                .attr('class', 'labels')
                .selectAll('text')
                .data(data.nodes)
                .enter().append('text')
                .text(d => d.name)
                .attr('font-size', '10px')
                .attr('dx', 12)
                .attr('dy', 4);

            // 更新力模拟
            graphSimulation.on('tick', () => {
                link
                    .attr('x1', d => d.source.x)
                    .attr('y1', d => d.source.y)
                    .attr('x2', d => d.target.x)
                    .attr('y2', d => d.target.y);

                node
                    .attr('cx', d => d.x)
                    .attr('cy', d => d.y);

                text
                    .attr('x', d => d.x)
                    .attr('y', d => d.y);
            });

            // 拖拽函数
            function dragstarted(event, d) {
                if (!event.active) graphSimulation.alphaTarget(0.3).restart();
                d.fx = d.x;
                d.fy = d.y;
            }

            function dragged(event, d) {
                d.fx = event.x;
                d.fy = event.y;
            }

            function dragended(event, d) {
                if (!event.active) graphSimulation.alphaTarget(0);
                d.fx = null;
                d.fy = null;
            }

            // 缩放功能
            graphZoom = d3.zoom()
                .scaleExtent([0.1, 4])
                .on('zoom', (event) => {
                    g.attr('transform', event.transform);
                });

            svg.call(graphZoom);
        }

        function zoomIn() {
            d3.select('#knowledge-graph').transition().call(graphZoom.scaleBy, 1.5);
        }

        function zoomOut() {
            d3.select('#knowledge-graph').transition().call(graphZoom.scaleBy, 0.75);
        }

        function refreshGraph() {
            initKnowledgeGraph();
        }

        function showNodeDetails(event, d) {
            alert(`节点详情:\n名称: ${d.name}\n类型: ${d.type}\nID: ${d.id}`);
        }

        // 搜索功能
        async function performSearch() {
            const query = document.getElementById('global-search').value.trim();
            if (!query) {
                alert('请输入搜索关键词');
                return;
            }

            // 切换到搜索选项卡
            document.querySelectorAll('.menu-link').forEach(item => {
                item.classList.remove('active');
                if (item.getAttribute('data-target') === 'search') {
                    item.classList.add('active');
                }
            });

            document.querySelectorAll('.content-section').forEach(section => {
                section.style.display = 'none';
            });
            document.getElementById('search').style.display = 'block';

            try {
                const response = await fetch(`/api/kg/search?q=${encodeURIComponent(query)}&limit=10`);
                const data = await response.json();
                displaySearchResults(data);
            } catch (error) {
                console.error('Search Error:', error);
                alert('搜索失败');
            }
        }

        function displaySearchResults(data) {
            const resultsContainer = document.getElementById('search-results');
            if (data.results && data.results.length > 0) {
                let html = `<h3>搜索结果 (${data.results.length} 条):</h3>`;
                data.results.forEach(result => {
                    const name = result.name || result.title || '未知名称';
                    const type = result.labels ? result.labels[0] : '未知类型';
                    html += `
                        <div class="relation-item">
                            <h4>${name}</h4>
                            <p>类型: ${type}</p>
                            <p>ID: ${result.id}</p>
                        </div>
                    `;
                });
                resultsContainer.innerHTML = html;
            } else {
                resultsContainer.innerHTML = '<p>未找到相关结果</p>';
            }
        }

        function exportResults() {
            alert('导出功能即将实现...');
        }

        // 初始化页面
        window.addEventListener('load', function() {
            // 默认显示NER选项卡
            document.getElementById('ner').style.display = 'block';
        });
    </script>
</body>
</html>